﻿using System;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Abp;
using Abp.Application.Services.Dto;
using Abp.Auditing;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.Notifications;
using Abp.Runtime.Session;
using Microsoft.EntityFrameworkCore;
using pandx.Mulan.Notifications.Dto;
using Abp.Linq.Extensions;

namespace pandx.Mulan.Notifications
{
    public class NotificationAppService:MulanAppServiceBase,INotificationAppService
    {
        private readonly INotificationDefinitionManager _notificationDefinitionManager;
        private readonly IUserNotificationManager _userNotificationManager;
        private readonly INotificationSubscriptionManager _notificationSubscriptionManager;

        // private readonly IRepository<TenantNotificationInfo, Guid> _tenantNotificationInfoRepository;
        // private readonly IRepository<UserNotificationInfo, Guid> _userNotificationInfoRepository;

        public NotificationAppService(
            INotificationDefinitionManager notificationDefinitionManager,
            IUserNotificationManager userNotificationManager,
            INotificationSubscriptionManager notificationSubscriptionManager
            // IRepository<TenantNotificationInfo,Guid> tenantNotificationInfoRepository,
            // IRepository<UserNotificationInfo,Guid> userNotificationInfoRepository
            )
        {
            _notificationDefinitionManager = notificationDefinitionManager;
            _userNotificationManager = userNotificationManager;
            _notificationSubscriptionManager = notificationSubscriptionManager;
            // _tenantNotificationInfoRepository = tenantNotificationInfoRepository;
            // _userNotificationInfoRepository = _userNotificationInfoRepository;
        }

        [DisableAuditing]
        [AbpAuthorize]
        public async Task<GetNotificationsOutput> GetUserNotifications(GetUserNotificationsInput input)
        {
            var totalCount =
                await _userNotificationManager.GetUserNotificationCountAsync(AbpSession.ToUserIdentifier(),
                    input.State);
            var unreadCount =
                await _userNotificationManager.GetUserNotificationCountAsync(AbpSession.ToUserIdentifier(),
                    UserNotificationState.Unread);
            var notifications = await _userNotificationManager.GetUserNotificationsAsync(AbpSession.ToUserIdentifier(),
                input.State, input.SkipCount, input.MaxResultCount, input.StarTime, input.EndTime);
            // var un=notifications
            //     .Where(n => n.Notification.NotificationName == AppNotifications.ConcurrentLoginPerUser).ToList();
            // foreach (var n in un)
            // {
            //     await _userNotificationManager.UpdateUserNotificationStateAsync(AbpSession.TenantId, n.Id,
            //         UserNotificationState.Read);
            // }
            
            // var query = from u in _userNotificationInfoRepository.GetAll()
            //     join t in _tenantNotificationInfoRepository.GetAll() on u.TenantNotificationId equals t.Id
            //     where u.CreationTime >= input.StarTime && u.CreationTime <= input.EndTime && t.NotificationName!="App.ConcurrentLoginPerUser"
            //     && u.UserId==AbpSession.UserId && u.TenantId==AbpSession.TenantId
            //     select new
            //     {
            //         U = u,
            //         T = t,
            //     };
            // query = query.WhereIf(input.State.HasValue, x => x.U.State == input.State);
            // var totalCount = query.Count();
            // var unreadCount = query.Count(q => q.U.State == UserNotificationState.Read);
            // query = query.OrderByDescending(q => q.U.CreationTime).Skip(input.SkipCount)
            //     .Take(input.MaxResultCount);
            // var notificationList = await query.ToListAsync();
            // var notifications = notificationList.Select(item =>
            // {
            //     var notification = ObjectMapper.Map<UserNotification>(item.U);
            //     notification.Notification = ObjectMapper.Map<TenantNotification>(item.T);
            //     return notification;
            // }).ToList();
            
            return new GetNotificationsOutput(totalCount, unreadCount, notifications);


        }
        [AbpAuthorize]
        public async Task SetAllNotificationsAsRead()
        {
            await _userNotificationManager.UpdateAllUserNotificationStatesAsync(AbpSession.ToUserIdentifier(),
                UserNotificationState.Read);
        }
        [AbpAuthorize]
        public async Task SetNotificationAsRead(EntityDto<Guid> input)
        {
            var userNotification =
                await _userNotificationManager.GetUserNotificationAsync(AbpSession.TenantId, input.Id);
            if (userNotification == null)
            {
                return;
            }

            if (userNotification.UserId != AbpSession.GetUserId())
            {
                throw new Exception($"ID {input.Id} 不属于当前用户 {AbpSession.GetUserId()}");
            }

            await _userNotificationManager.UpdateUserNotificationStateAsync(AbpSession.TenantId, input.Id,
                UserNotificationState.Read);
        }
        [AbpAuthorize]
        public Task<GetNotificationSettingsOutput> GetNotificationSettings()
        {
            
            return null;
        }
        [AbpAuthorize]
        public Task UpdateNotificationSettings(UpdateNotificationSettingsInput input)
        {
            return null;
        }
        [AbpAuthorize]
        public async Task DeleteNotification(EntityDto<Guid> input)
        {
            var notification =
                await _userNotificationManager.GetUserNotificationAsync(AbpSession.TenantId, input.Id);
            if (notification == null)
            {
                return;
            }

            if (notification.UserId != AbpSession.GetUserId())
            {
                throw new Exception($"ID {input.Id} 不属于当前用户 {AbpSession.GetUserId()}");
            }

            await _userNotificationManager.DeleteUserNotificationAsync(AbpSession.TenantId, input.Id);
        }
        [AbpAuthorize]
        public async Task DeleteAllUserNotifications(DeleteAllUserNotificationsInput input)
        {
            await _userNotificationManager.DeleteAllUserNotificationsAsync(AbpSession.ToUserIdentifier(), input.State,
                input.StartTime, input.EndTime);
        }
        [AbpAuthorize]
        public async Task BatchDeleteNotifications(Guid[] ids)
        {
            foreach (var id in ids)
            {
                var notification =
                    await _userNotificationManager.GetUserNotificationAsync(AbpSession.TenantId, id);
                if (notification == null)
                {
                    return;
                }

                if (notification.UserId != AbpSession.GetUserId())
                {
                    throw new Exception($"ID {id} 不属于当前用户 {AbpSession.GetUserId()}");
                }

                await _userNotificationManager.DeleteUserNotificationAsync(AbpSession.TenantId, id);
            }
        }
    }
}